package io.sdl.controller;

import cn.hutool.core.date.DateTime;
import io.sdl.common.sys.service.SdlDoctorsService;
import io.sdl.common.sys.service.SdlMessageReadStatusService;
import io.sdl.common.utils.PageUtils;
import io.sdl.common.utils.Query;
import io.sdl.common.utils.Result;
import io.sdl.common.constant.UrlConstants;
import io.sdl.dto.CommentDTO;
import io.sdl.dto.DiaryUserDTO;
import io.sdl.dto.SdlDiariesDTO;
import io.sdl.dto.SdlDiaryCommentsDTO;
import io.sdl.entity.*;
import io.sdl.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 矫形日记表
 *
 * @author Dchen
 * @email 1211734836@qq.com
 * @date 2025-04-25 14:09:19
 */
@RestController
@RequestMapping("/api")
public class ApiSdlDiariesController {

    @Autowired
    private SdlDiariesService sdlDiariesService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private UserService userService;

    @Autowired
    private SdlDiaryCommentsService sdlDiaryCommentsService;

    @Autowired
    private SdlLikesService sdlLikesService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SdlMessageReadStatusService sdlMessageReadStatusService;

    //查询日记记录
    @GetMapping("getDiaries")
    @Operation(summary = "查询日记记录")
    private Result<HashMap<Object, Object>> getDiaries(@Parameter(hidden = true) @RequestParam Map<String, Object> params) {

        if (params.get("token") != null && !params.get("token").equals("")) {
            String userRole = (String) params.get("userRole");
            Long roleId = sysRoleService.getRoleByRemark(userRole).getId();
            TokenEntity byToken = tokenService.getByToken(params.get("token").toString());
            tokenService.expireToken(byToken.getUserId(),true);

            Query query = new Query(params);

            //用户基本信息获取
            UserEntity user = userService.getUserByUserId(byToken.getUserId());


            user.setAvatarUrl(UrlConstants.getProductionUrl()+user.getAvatarUrl());


            Integer total = sdlDiariesService.getNum(user.getId());

            //获取动态记录
            List<SdlDiariesDTO> diaryList = sdlDiariesService.selectByUserId(user.getId(),roleId, query.getPage(), query.getLimit());

            //遍历动态
            diaryList.forEach(d -> {
                //根据动态id获取下面的评论
                List<SdlDiaryCommentsDTO> diaryCommentsDtoList = sdlDiaryCommentsService.selectByDiaryId(d.getId());

                //查看用户有没有对此条动态点赞
                SdlLikesEntity sdlLikesEntity = sdlLikesService.selectByUserId(user.getId(), d.getId());
                if (sdlLikesEntity != null) {
                    d.setIsLiked(true);
                }
                //是否展示评论标识
                d.setShowComments(false);

                //通过变量来获取评论下面的评论
                diaryCommentsDtoList.forEach(comments -> {
                    //保存评论人的信息
                    UserEntity commentator = userService.selectById(comments.getUserId());
                    DiaryUserDTO diaryUserDto = new DiaryUserDTO();
                    diaryUserDto.setId(commentator.getId());
                    diaryUserDto.setNickName(commentator.getNickName());
                    diaryUserDto.setAvatarUrl(commentator.getAvatarUrl() != null ? commentator.getAvatarUrl() : "");
                    diaryUserDto.setUsername(commentator.getUsername() != null ? commentator.getUsername() : "");


                    comments.setDiaryUserDto(diaryUserDto);
                    //获取一级评论下的二级评论
                    flattenAllRepliesToRoot(comments);
                });
                d.setCommentList(diaryCommentsDtoList);
            });

            PageUtils pageUtils = new PageUtils(diaryList, total, query.getLimit(), query.getPage());
            HashMap<Object, Object> map = new HashMap<>();
            map.put("userInfo", user);
            map.put("pageUtils", pageUtils);
            return new Result<HashMap<Object, Object>>().ok(map);
        }

        return new Result().error(400, "长时间未操作,请重新登录");
    }

    //专家简介页面的动态列表查询
    @GetMapping("getDoctorDiaries")
    @Operation(summary = "专家简介页面的动态列表查询")
    private Result<HashMap<Object, Object>> getDoctorDiaries(@Parameter(hidden = true) @RequestParam Map<String, Object> params) {

        if (params.get("doctorId") != null && !params.get("doctorId").equals("")) {

            TokenEntity byToken = tokenService.getByToken(params.get("token").toString());
            tokenService.expireToken(byToken.getUserId(),true);
            UserEntity doctorInfo = userService.selectById(params.get("doctorId").toString());

            String userRole = (String) params.get("userRole");
            Long roleId = sysRoleService.getRoleByRemark(userRole).getId();

            Query query = new Query(params);

            Integer total = sdlDiariesService.getNum(doctorInfo.getId());

            //获取动态记录
            List<SdlDiariesDTO> diaryList = sdlDiariesService.selectByUserId(doctorInfo.getId(),roleId, query.getPage(), query.getLimit());

            //遍历动态
            diaryList.forEach(d -> {
                //根据动态id获取下面的评论
                List<SdlDiaryCommentsDTO> diaryCommentsDtoList = sdlDiaryCommentsService.selectByDiaryId(d.getId());

                //查看用户有没有对此条动态点赞
                SdlLikesEntity sdlLikesEntity = sdlLikesService.selectByUserId(byToken.getUserId(), d.getId());
                if (sdlLikesEntity != null) {
                    d.setIsLiked(true);
                }
                //是否展示评论标识
                d.setShowComments(false);

                //通过变量来获取评论下面的评论
                diaryCommentsDtoList.forEach(comments -> {
                    //保存评论人的信息
                    UserEntity commentator = userService.selectById(comments.getUserId());
                    DiaryUserDTO diaryUserDto = new DiaryUserDTO();
                    diaryUserDto.setId(commentator.getId());
                    diaryUserDto.setNickName(commentator.getNickName());
                    diaryUserDto.setAvatarUrl(commentator.getAvatarUrl() != null ? commentator.getAvatarUrl() : "");
                    diaryUserDto.setUsername(commentator.getUsername() != null ? commentator.getUsername() : "");


                    comments.setDiaryUserDto(diaryUserDto);
                    //获取一级评论下的二级评论
                    flattenAllRepliesToRoot(comments);
                });
                d.setCommentList(diaryCommentsDtoList);
            });

            PageUtils pageUtils = new PageUtils(diaryList, total, query.getLimit(), query.getPage());
            HashMap<Object, Object> map = new HashMap<>();
            map.put("userInfo", doctorInfo);
            map.put("pageUtils", pageUtils);
            return new Result<HashMap<Object, Object>>().ok(map);
        }

        return new Result().error(400, "长时间未操作,请重新登录");
    }
    @GetMapping("diaries/detail")
    @Operation(summary = "获取动态详情")
    private Result getDiariesDetail(@Parameter(hidden = true) @RequestParam Map<String, Object> params) {
        if (params.get("token") != null && !params.get("token").equals("")) {

            TokenEntity byToken = tokenService.getByToken(params.get("token").toString());
            tokenService.expireToken(byToken.getUserId(),true);

            SdlDiariesEntity entity = sdlDiariesService.getDiariesDetail(Long.valueOf(params.get("id").toString()));

            return new Result().ok(entity);
        }
        return new Result().error(400, "长时间未操作,请重新登录");
    }

    // 提交评论或回复
    @PostMapping("comment/add")
    @Operation(summary = "提交评论或回复")
    private Result<Long> commentAdd(@RequestBody CommentDTO commentDto) {

        if (commentDto.getToken() != null && !commentDto.getToken().equals("")) {

            TokenEntity byToken = tokenService.getByToken(commentDto.getToken());
            tokenService.expireToken(byToken.getUserId(),true);

            SdlDiaryCommentsEntity comment = new SdlDiaryCommentsEntity();

            Long diaryId = Long.valueOf(commentDto.getDiaryId());
            SdlDiariesEntity diariesEntity = sdlDiariesService.selectById(diaryId);
            if (diariesEntity == null) {
                return new Result().error(502, "该条动态已删除");
            }
            //保存动态id
            comment.setDiaryId(diaryId);

            comment.setUserId(byToken.getUserId());
            //判断此条评论是回复动态还是评论
            if (commentDto.getParentId() != null) {
                Long parentId = Long.valueOf(commentDto.getParentId());

                SdlDiaryCommentsEntity sdlDiaryCommentsEntity = sdlDiaryCommentsService.selectById(parentId);

                if (sdlDiaryCommentsEntity == null) {
                    return new Result().error(502, "该评论已删除");
                }

                //保存回复的评论信息
                comment.setParentId(parentId);

                comment.setReplyTo(sdlDiaryCommentsEntity.getReplyTo());

            } else {
                comment.setParentId(0L);
            }

            comment.setContent(commentDto.getContent());
            comment.setStatus(1);
            comment.setCreatedAt(DateTime.now());
            comment.setUpdatedAt(DateTime.now());
            sdlDiaryCommentsService.insert(comment);

            // 获取动态作者
            Long authorId = sdlDiariesService.selectById(comment.getDiaryId()).getUserId();
            // 如果不是自己评论自己的动态，则添加未读记录
            if (!authorId.equals(comment.getUserId())) {
                sdlMessageReadStatusService.addUnreadRecord(
                        comment.getId(),
                        1, // 1表示评论类型
                        authorId
                );
            }
            diariesEntity.setCommentCount(diariesEntity.getCommentCount() + 1);
            sdlDiariesService.updateById(diariesEntity);
            return new Result<Long>().ok(comment.getId());
        }

        return new Result().error(400, "长时间未操作,请重新登录");

    }

    @PostMapping("comment/delete")
    @Operation(summary = "删除评论")
    private Result commentDel(@RequestBody CommentDTO dto){
        if(dto.getToken() != null && !dto.getToken().equals("")){
            TokenEntity byToken = tokenService.getByToken(dto.getToken());
            tokenService.expireToken(byToken.getUserId(),true);
            //获取评论的评论人id
            SdlDiaryCommentsEntity comment = sdlDiaryCommentsService.selectById(dto.getCommentId());

            //查询日记评论数
            SdlDiariesEntity diariesEntity = sdlDiariesService.selectById(comment.getDiaryId());
            if(diariesEntity == null){
                return new Result().error( 404,"动态不存在");
            }
            //评论数
            Integer commentCount = diariesEntity.getCommentCount();
            //动态发布人或者评论人可以删除当前评论
            if(byToken.getUserId().equals(diariesEntity.getUserId()) || byToken.getUserId().equals(comment.getUserId())){

                sdlDiaryCommentsService.deleteById(dto.getCommentId());
                commentCount = commentCount - 1;

                //删除当前评论下的子评论
                List<SdlDiaryCommentsDTO> commentsList = sdlDiaryCommentsService.selectByPid(Long.valueOf(dto.getCommentId()));
                for ( int i = 0 ; i<commentsList.size();i++){
                    sdlDiaryCommentsService.deleteById(commentsList.get(i).getId());
                    commentCount = commentCount - 1;
                    commentCount = cDel(commentCount, commentsList.get(i).getId());
                }

                diariesEntity.setCommentCount(commentCount);
                sdlDiariesService.updateById(diariesEntity);
                return new Result();
            }else{
                return new Result().error( 200,"只能删除自己的评论");
            }
        }
        return new Result().error(400, "长时间未操作,请重新登录");
    }

    private int cDel(Integer commentCount, Long id){
        List<SdlDiaryCommentsDTO> commentsDTOList = sdlDiaryCommentsService.selectByPid(id);
        if(commentsDTOList.size() > 0){
            for ( int i = 0 ; i<commentsDTOList.size();i++){
                sdlDiaryCommentsService.deleteById(commentsDTOList.get(i).getId());
                commentCount = commentCount - 1;
                cDel(commentCount,commentsDTOList.get(i).getId());
            }
        }
        return commentCount;
    }

    @PostMapping("like/add")
    @Operation(summary = "点赞/取消点赞")
    private Result<String> likeAdd(@RequestBody CommentDTO commentDto) {
        if (commentDto.getToken() != null && !commentDto.getToken().equals("")) {

            TokenEntity byToken = tokenService.getByToken(commentDto.getToken());
            tokenService.expireToken(byToken.getUserId(),true);

            //查看是否已经有过点赞
            SdlLikesEntity sdlLikes = sdlLikesService.selectByUserId(byToken.getUserId(), commentDto.getDiaryId());
            //查询点赞/取消点赞的动态
            SdlDiariesEntity diariesEntity = sdlDiariesService.selectById(commentDto.getDiaryId());

            if (sdlLikes == null) {

                //点赞数量+1
                diariesEntity.setLikeCount(diariesEntity.getLikeCount() + 1);
                sdlDiariesService.updateById(diariesEntity);
                //记录用户动态点赞关联
                SdlLikesEntity likeAdd = new SdlLikesEntity();

                likeAdd.setUserId(byToken.getUserId());
                likeAdd.setTargetId(commentDto.getDiaryId());
                likeAdd.setTargetType(1);
                likeAdd.setCreatedAt(DateTime.now());

                sdlLikesService.insert(likeAdd);

                return new Result<String>().ok("点赞成功");
            } else {

                //如果有点赞记录则需要删除点赞记录并将动态点赞数量-1
                diariesEntity.setLikeCount(diariesEntity.getLikeCount() - 1);
                sdlDiariesService.updateById(diariesEntity);

                sdlLikesService.deleteById(sdlLikes.getId());
                return new Result<String>().ok("取消点赞成功");
            }
        }

        return new Result().error(400, "长时间未操作,请重新登录");
    }


    @PostMapping("diaries/add")
    @Operation(summary = "发布矫形动态")
    private Result<Long> diariesAdd(@RequestBody SdlDiariesDTO diaries) {
        if (diaries.getToken() != null && !diaries.getToken().equals("")) {

            TokenEntity byToken = tokenService.getByToken(diaries.getToken());
            tokenService.expireToken(byToken.getUserId(),true);
            SdlDiariesEntity entity = new SdlDiariesEntity();

            entity.setUserId(byToken.getUserId());
            entity.setRoleId(sysRoleService.getRoleByRemark(diaries.getUserRole()).getId());
            entity.setContent(diaries.getContent());
            entity.setLikeCount(0);
            entity.setCommentCount(0);
            entity.setIsPublic(1);
            entity.setCreatedAt(DateTime.now());
            entity.setUpdatedAt(DateTime.now());
            entity.setStatus(1);
            sdlDiariesService.insert(entity);


            return new Result<Long>().ok(entity.getId());
        }

        return new Result().error(400, "长时间未操作,请重新登录");

    }

    @PostMapping("diaries/update")
    @Operation(summary = "编辑矫形动态")
    private Result<Long> diariesUpdate(@RequestBody SdlDiariesDTO diaries) {

        if (diaries.getToken() != null && !diaries.getToken().equals("")) {

            TokenEntity byToken = tokenService.getByToken(diaries.getToken());
            tokenService.expireToken(byToken.getUserId(),true);


            SdlDiariesEntity entity = new SdlDiariesEntity();
            entity.setId(diaries.getId());
            entity.setRoleId(sysRoleService.getRoleByRemark(diaries.getUserRole()).getId());
            entity.setContent(diaries.getContent());
            entity.setImages((diaries.getImages()!=null&&!diaries.getImages().equals(""))?diaries.getImages():null);
            entity.setUpdatedAt(DateTime.now());
            sdlDiariesService.updateById(entity);
            return new Result<>();
        }
        return new Result().error(400, "长时间未操作,请重新登录");

    }

    @PostMapping("upload/diaries")
    @Operation(summary = "动态图片上传")
    public Result uploadPatient(@RequestParam(value = "file", required = false) MultipartFile file, Long id) {
        try {
            // 1. 保存文件并返回地址
            sdlDiariesService.saveUploadedFile(file, id);

            SdlDiariesEntity diariesEntity = sdlDiariesService.selectById(id);
            return new Result().ok(diariesEntity);
        } catch (Exception e) {
            return new Result().error(500, "文件上传失败: " + e.getMessage());

        }
    }


    // 删除动态
    @PostMapping("deleteDiary")
    @Operation(summary = "删除动态")
    private Result deleteDiary(@RequestBody SdlDiariesDTO diaries) {
        if (diaries.getToken() != null && !diaries.getToken().equals("")) {

            TokenEntity byToken = tokenService.getByToken(diaries.getToken());
            tokenService.expireToken(byToken.getUserId(),true);

            sdlDiariesService.deleteById(diaries.getId());
            return new Result<>();
        }

        return new Result().error(400, "长时间未操作,请重新登录");
    }

    /*
     * rootComment 一级评论
     */
    private SdlDiaryCommentsDTO flattenAllRepliesToRoot(SdlDiaryCommentsDTO rootComment) {
        // 1. 获取一级评论的直接子评论（二级评论）
        List<SdlDiaryCommentsDTO> directReplies = sdlDiaryCommentsService.selectByPid(rootComment.getId());
        List<SdlDiaryCommentsDTO> allReplies = new ArrayList<>(directReplies);

        // 2. 递归获取所有深层级评论（三级、四级...）
        for (SdlDiaryCommentsDTO reply : directReplies) {
            fetchAllNestedReplies(reply, allReplies);
        }

        // 3. 将所有评论（二级、三级、四级...）挂到一级评论下
        rootComment.setReplies(allReplies);

        // 4. 初始化所有评论的用户信息
        for (SdlDiaryCommentsDTO comment : allReplies) {
            comment.setShowComments(false);
            UserEntity commentator = userService.selectById(comment.getUserId());
            DiaryUserDTO diaryUserDto = new DiaryUserDTO();
            diaryUserDto.setId(commentator.getId());

            UserEntity user = userService.selectById(sdlDiaryCommentsService.selectById(comment.getParentId()).getUserId());
            if (user.getId().equals(comment.getUserId())) {
                diaryUserDto.setNickName(commentator.getNickName() + " 回复 ");
            } else {
                diaryUserDto.setNickName(commentator.getNickName() + " 回复 " + user.getNickName());
            }

            diaryUserDto.setAvatarUrl(commentator.getAvatarUrl() != null ? commentator.getAvatarUrl() : "");
            diaryUserDto.setUsername(commentator.getUsername() != null ? commentator.getUsername() : "");
            comment.setDiaryUserDto(diaryUserDto);
        }

        return rootComment;
    }

    /**
     * 递归获取某个评论下的所有嵌套回复（三级、四级...），并添加到目标列表
     */
    private void fetchAllNestedReplies(SdlDiaryCommentsDTO comment, List<SdlDiaryCommentsDTO> targetList) {
        List<SdlDiaryCommentsDTO> nestedReplies = sdlDiaryCommentsService.selectByPid(comment.getId());
        if (!nestedReplies.isEmpty()) {
            targetList.addAll(nestedReplies);
            for (SdlDiaryCommentsDTO nestedReply : nestedReplies) {
                fetchAllNestedReplies(nestedReply, targetList); // 继续递归更深层级
            }
        }
    }


}
